package cn.tedu.apiday09;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

//测试反射
public class Reflex {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //method();//反射class对象
        //method2();//反射构造方法
        //method3();//反射成员变量
      // method4();//反射成员方法
       method5();//反射创建实例




    }

    private static void method5() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //获取Class对象
        Class c = Runn.class;
        //调用方法，创建对象
        //newInstance()返回值类型是object类型
        Runn runn = (Runn) c.newInstance();//底层会自动触发无参构造
        System.out.println(runn);
        //触发含参构造，创建对象
        //指定想要触发哪个含参构造==指定参数类型的Class对象
        Constructor c1 = c.getConstructor(String.class,int.class);
        //触发指定的构造方法，并创建对象
        Object o = c1.newInstance("孙",18);
        System.out.println(o);
    }

    private static void method4() {
        //获取Class对象
        Runn runn = new Runn();
        Class c =runn.getClass();
        //获取所有public的成员方法们
        Method[] methods = c.getMethods();
        //遍历数组，获取每个成员方法
        for (Method m:methods
             ) {
            System.out.println(m.getName());//获取成员方法名
            //获取方法的参数类型
            Class[] c1 = m.getParameterTypes();
            System.out.println(Arrays.toString(c1));
        }

    }

    private static void method3() {

        //获取Class对象
        Class c = Runn.class;
        //调用方法获取所有public的成员变量们
        Field[] fields = c.getFields();
        //遍历数组，获取每个成员变量
        for (Field f:fields
             ) {
            System.out.println(f.getName());//获取变量名
            //获取变量类型
            System.out.println(f.getType().getName());
        }

    }

    private static void method2() throws ClassNotFoundException {
        //获取Class对象
        Class c1= Class.forName("cn.tedu.apiday09.Runn");
        //调用方法，获取所有public的构造方法们
        Constructor[] constructors = c1.getConstructors();
        //遍历数组，获取每个构造方法
        for (Constructor c:constructors
             ) {
            System.out.println(c.getName());//获取构造方法的名称
            //获取构造方法的参数类型们
            Class[] css = c.getParameterTypes();
            System.out.println(Arrays.toString(css));
        }




    }

    private static void method() throws ClassNotFoundException {
        //Class.forName(类的全路径)
        Class c1 = Class.forName("cn.tedu.apiday09.Runn");//获取Class对象的一种方式
        System.out.println(c1);
        //类名.class
        Class c2 = Runn.class;//获取Class对象的一种方式
        System.out.println(c2);
        //对象.getClass()
        Class c3 = new Runn().getClass();//匿名对象   从父类Object继承过来的getClass（）//获取Class对象的一种方式
        System.out.println(c3);
        System.out.println(c1==c2);
        System.out.println(c1==c3);
        System.out.println(c2==c3);
        System.out.println(c1.getPackage().getName());//获取包名
        System.out.println(c1.getSimpleName());//获取类名
        System.out.println(c1.getName());//获取全路径





    }
}
